
//Eli Elder
//buycard


#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "rngs.h"

//set PRINTOUT to 0 to remove printfs out
#define PRINTOUT 1
#define ASSERTIVE 0
#define PRINTOUTASSERT 1

int checkBuyCard(int supplyPos, struct gameState *afterBuyState){
    struct gameState beforeBuyState;
    int returnVal;
    int player;    
    //copy so we can test if the buy card worked how we think it should
    memcpy(&beforeBuyState, afterBuyState, sizeof(struct gameState));
    //do the buy card
    returnVal = buyCard(supplyPos, afterBuyState);
    
#if (PRINTOUT == 1)
    //printout some information
    printf("number of buys %d, cost %d, number of coins %d \n", beforeBuyState.numBuys, getCost(supplyPos), beforeBuyState.coins); 

	//check num buys before we do it
	if(beforeBuyState.numBuys < 1){
		printf("not enough buys\n");
	}
	//check supply coint before we do it
	if(supplyCount(supplyPos, &beforeBuyState) < 1){
		printf("not enough supply\n");
	}

	//check cost before we do it
	if(beforeBuyState.coins < getCost(supplyPos)){
		printf("not enough coins\n");
	}
#endif

    //need to set the player up
    player = beforeBuyState.whoseTurn;
    //push the phase to phase 1, I guess that means next phase
    beforeBuyState.phase = 1; 
    //lower the cost of the card
    beforeBuyState.coins = (beforeBuyState.coins) - (getCost(supplyPos));
    //lower the amount of buys possible
    beforeBuyState.numBuys--;

    //we also gain a card, don't test this we would test this elsewhere unless you really want to
    gainCard(supplyPos, &beforeBuyState, 0, player);

#if (PRINTOUT == 1)    
    //if the full deck counts arent the same gain and discard messed up

	if(fullDeckCount(player, supplyPos, &beforeBuyState) < fullDeckCount(player, supplyPos, afterBuyState)){
		printf("The Buycard has more cards than the test\n");
	} else if(fullDeckCount(player, supplyPos, &beforeBuyState) > fullDeckCount(player, supplyPos, afterBuyState)){
		printf("The Buycard has less cards than the test\n");
	}

	//check the hand cards
	if(beforeBuyState.handCount[player] < afterBuyState->handCount[player]){
		printf("The Buycard has more hand cards than the test\n");
	} else if(beforeBuyState.handCount[player] > afterBuyState->handCount[player]){
		printf("The Buycard has less hand cards than the test\n");
	}

	
	//check that coins are correct
	if(beforeBuyState.coins < afterBuyState->coins){
		printf("The Buy state has more coins than the test\n");
	} else if(beforeBuyState.coins > afterBuyState->coins){
		printf("The Buy state has less coins than the test\n");
	}
	
	//check that buys are correct
	if(beforeBuyState.numBuys < afterBuyState->numBuys){
		printf("The Buy state has more numBuys than the test\n");
	} else if(beforeBuyState.numBuys > afterBuyState->numBuys){
		printf("The Buy state has less numBuys than the test\n");
	}
	
	//check that phase is correct 
	if(beforeBuyState.phase < afterBuyState->phase){
		printf("The Buy state phase is higher than the test\n");
	} else if(beforeBuyState.phase > afterBuyState->phase){
		printf("The Buy state phase is less than the test\n");
	}
#endif	
#if (ASSERTIVE == 1)
    //tests that we returned 0, checking if they can buy, have enough coins, or have enough supply
    assert(returnVal == 0);
    //assert that the after buyCard state is the same as we expect it to be with the "before" that we made like the after
    assert(memcmp(&beforeBuyState, afterBuyState, sizeof(struct gameState)) == 0);
#endif
#if (PRINTOUTASSERT == 1)
    //tests that we returned 0, checking if they can buy, have enough coins, or have enough supply                                                                                 
    //assert(returnVal == 0);
    //assert that the after buyCard state is the same as we expect it to be with the "before" that we made like the after                                                          
    //assert(memcmp(&beforeBuyState, afterBuyState, sizeof(struct gameState)) == 0);

    //prints this out if we pass the assert meaning it worked
    printf("The player just bought a ");
    //print off the card                                                                                                                                                       
    switch(supplyPos){
    case adventurer: printf("adventurer"); break;
    case copper: printf("copper"); break;
    case feast: printf("feast"); break;
    case gardens: printf("gardens"); break;
    case curse: printf("curse"); break;
    case remodel: printf("remodel"); break;
    case smithy: printf("smithy"); break;
    case village: printf("village"); break;
    case baron: printf("baron"); break;
    case salvager: printf("salvager"); break;
    }
    
    printf(" for %d\n", getCost(supplyPos));
#endif

    return 0;
 }

int main() {
    int player = 1;
    int cardSupply;
    int i;
    int numDiscard = 5;
    int numHand = 6;
    int numBuys = 1;
    int initialized;
    int coppers[MAX_DECK];
    //used to test when we have no tresures to buy a card
    int villages[MAX_DECK];
    struct gameState theGameState;
    int kingCards[10] = {adventurer, copper, feast, gardens, curse, remodel, smithy, village, baron, salvager};
    
    
    //this helps setup the random tests
    SelectStream(2);
    PutSeed(3);
    
    for(i = 0; i < MAX_DECK; i++){
	coppers[i] = copper;
    }

    
    //small fixed tests that loop through EVERYTHING!!!!!!
    for(cardSupply = 0; cardSupply < 10; cardSupply++){
	    //setup and initialize the state (should do in random?)
	    memset(&theGameState, 23, sizeof(struct gameState));
	    initialized = initializeGame(player, kingCards, 1, &theGameState);
	    
	    //assign the deck, hand, and discard
	    theGameState.discardCount[player] = numDiscard;
	    theGameState.handCount[player] = numHand;
	    
	    //dont need the deck so just do 0 for no seg faulsts
	    theGameState.deckCount[player] = 0; 
	    //mem set the deck hand and discard
	    memcpy(theGameState.discard[player], coppers, sizeof(int) * MAX_DECK);
	    memcpy(theGameState.hand[player], coppers, sizeof(int) * MAX_HAND);
	    
	    theGameState.numBuys = numBuys;
	    theGameState.supplyCount[kingCards[cardSupply]] = 5; 
	    theGameState.whoseTurn = player;
	    
	    //update the coins
	    updateCoins(player, &theGameState, 0);
		
#if (PRINTOUT == 1) 
	//prints this out if we pass the assert meaning it worked
    printf("Trying to buy the card ");
    //print off the card                                                                                                                                                       
    switch(kingCards[cardSupply]){
    case adventurer: printf("adventurer"); break;
    case copper: printf("copper"); break;
    case feast: printf("feast"); break;
    case gardens: printf("gardens"); break;
    case curse: printf("curse"); break;
    case remodel: printf("remodel"); break;
    case smithy: printf("smithy"); break;
    case village: printf("village"); break;
    case baron: printf("baron"); break;
    case salvager: printf("salvager"); break;
    }
#endif

	    //do the test
	    checkBuyCard(kingCards[cardSupply], &theGameState);
    }
    
#if (PRINTOUT == 1) 
	printf("Trying to buy a card with supply 0\n");
#endif
    //do the check buy when the card supply is at 0
    theGameState.numBuys = numBuys;
    theGameState.supplyCount[kingCards[cardSupply]] = 0;
    theGameState.whoseTurn = player;
    
    //update the coins
    updateCoins(player, &theGameState, 0);
    //do the test
    checkBuyCard(kingCards[cardSupply], &theGameState);
 
#if (PRINTOUT == 1) 
	printf("Trying to buy a card with number of buys 0\n");
#endif 
    //do the check buy when the numBuys < 1
    //setup and initialize the state
    theGameState.numBuys = 0;
    theGameState.supplyCount[kingCards[cardSupply]] = 1;
    theGameState.whoseTurn = player;
    
    //update the coins
    updateCoins(player, &theGameState, 0);
    //do the test
    checkBuyCard(kingCards[cardSupply], &theGameState);
    
    //do the check buy when the hand has not enough treasure. aka 0
    //fill the array full of villages to put in our hand
    for(i = 0; i < MAX_DECK; i++){
        villages[i] = village;
    }
    
    //mem set the deck hand and discard
    memcpy(theGameState.discard[player], villages, sizeof(int) * MAX_DECK);
    memcpy(theGameState.hand[player], villages, sizeof(int) * MAX_HAND);
    
    theGameState.numBuys = numBuys;
    theGameState.supplyCount[kingCards[cardSupply]] = 5;
    theGameState.whoseTurn = player;
   
#if (PRINTOUT == 1) 
	printf("Trying to buy a card with coins at 0\n");
#endif

    //update the coins
    updateCoins(player, &theGameState, 0);
    //do the test
    checkBuyCard(kingCards[cardSupply], &theGameState);

    return 0;
}
